package com.senyint.hip.fhir.web;

import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.impl.GenericClient;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.senyint.hip.fhir.interceptor.CaptureInterceptor;
import com.senyint.hip.fhir.util.DateUtils;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.*;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

/**
 * *******description*******
 * 预约
 * *************************
 *
 * @author ChenPan
 * @date 2019/7/1 14:25
 */
@RestController
@RequestMapping("/appointment")
public class AppointmentController extends FhirBaseController {

    @PostMapping()
    public String createAppointment(@RequestBody String data) {
        Appointment appointment = convertAppointment(data);

        CaptureInterceptor interceptor = new CaptureInterceptor();
        GenericClient client = newClient(tempData.getBaseServer(), interceptor);

        MethodOutcome out = client.create().resource(appointment).execute();

        return new Gson().toJson(out);

    }

    @PutMapping("/{id}")
    public String updateAppointment(@PathVariable("id") String id, @RequestBody String data) throws FHIRException {
        Appointment appointment = convertAppointment(data);

        CaptureInterceptor interceptor = new CaptureInterceptor();
        GenericClient client = newClient(tempData.getBaseServer(), interceptor);

        MethodOutcome out = client.update(id, appointment);

        return new Gson().toJson(out);

    }

    protected Appointment convertAppointment(String data) {
        JSONObject jsonObject = JSON.parseObject(data);

        Appointment appointment = new Appointment();
        appointment.addIdentifier()
                .setSystem("http://shdc.org.cn/org/xxxxxxxxxxx/appoint")
                .setValue(jsonObject.getString("appointmentId"));
        appointment.setStatus(Appointment.AppointmentStatus.BOOKED);

        appointment.addServiceType(new CodeableConcept()
                .addCoding(new Coding("http://terminology.hl7.org/CodeSystem/service-type",
                        jsonObject.getString("serviceTypeCode"),
                        jsonObject.getString("serviceTypeName"))));

        appointment.setAppointmentType(new CodeableConcept()
                .addCoding(new Coding("http://terminology.hl7.org/CodeSystem/v2-0276",
                        jsonObject.getString("appointmentTypeCode"),
                        jsonObject.getString("appointmentTypeName"))));

        appointment.setStart(DateUtils.string2Date(jsonObject.getString("startTime")));
        appointment.setEnd(DateUtils.string2Date(jsonObject.getString("endTime")));

        appointment.addParticipant()
                .setActor(
                        new Reference().setReference("Patient/"+jsonObject.getString("patientId"))
                                .setDisplay(jsonObject.getString("patientName")))
                .setRequired(Appointment.ParticipantRequired.REQUIRED)
                .setStatus(Appointment.ParticipationStatus.ACCEPTED);

        appointment.addParticipant()
                .addType(new CodeableConcept(
                        new Coding()
                                .setSystem("http://terminology.hl7.org/CodeSystem/v3-ParticipationType")
                                .setCode("ATND")))
                .setActor(
                        new Reference()/*.setReference(jsonObject.getString("visitDoctorCode"))*/
                                .setDisplay(jsonObject.getString("visitDoctorName")))
                .setRequired(Appointment.ParticipantRequired.REQUIRED)
                .setStatus(Appointment.ParticipationStatus.ACCEPTED);

        appointment.addParticipant()
                .setActor(
                        new Reference()/*.setReference(jsonObject.getString("visitDeptCode"))*/
                                .setDisplay(jsonObject.getString("visitDeptName")))
                .setRequired(Appointment.ParticipantRequired.REQUIRED)
                .setStatus(Appointment.ParticipationStatus.ACCEPTED);

        return appointment;
    }
}
